package com.cmpe451.nutty.dao;

import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.cmpe451.nutty.model.AppUrl;
import com.cmpe451.nutty.model.ExampleModel;
import com.cmpe451.nutty.model.Levels;
import com.cmpe451.nutty.model.Report;
import com.cmpe451.nutty.model.Role;
import com.cmpe451.nutty.model.User;

/**
 * Recipe dao contains the database access elements for users.
 * @author CmpE Group 2 Fall 2014 nuttyconfirmation@gmail.com
 *
 */
@Repository
public class UserDaoImpl extends BaseDaoImpl implements UserDao {

	@Override
	public User findUserById(Long userId) {
		return getHibernateTemplate().get(User.class, userId);
	}

	@Override
	public User findUserByEmail(String email) {
		Criteria criteria = createCriteria(User.class);
		criteria.add(Restrictions.eq("email", email));
		return (User) criteria.uniqueResult();
	}

	@Override
	public User findUserByUsername(String username) {
		Criteria criteria = createCriteria(User.class);
		criteria.add(Restrictions.eq("username", username));
		return (User) criteria.uniqueResult();
	}

	@Override
	public ExampleModel findModelByName(String username){
		Criteria criteria = createCriteria(ExampleModel.class);
		criteria.add(Restrictions.eq("username", username));
		return (ExampleModel) criteria.uniqueResult();
	}

	@Override
	public void saveUser(User user) {
		getHibernateTemplate().save(user);
	}

	@Override
	public void updateUser(User user) {
		user.setUpdateDate(new Date());
		getHibernateTemplate().update(user);
	}

	@Override
	public List<Role> findUserRoles(Long userId) {
		return null;
	}

	@Override
	public List<AppUrl> findAllSecureUrls() {
		return findAll(AppUrl.class);
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<User> findUsers(int page, int max, String orderBy, String orderType) {
		Criteria criteria = createCriteria(User.class);
		criteria.setFirstResult(max * page);
		criteria.setMaxResults(max);

		if (orderType != null && orderType.equalsIgnoreCase("desc")) {
			criteria.addOrder(Order.desc(orderBy));
		} else {
			criteria.addOrder(Order.asc(orderBy));
		}

		return criteria.list();
	}

	@Override
	public Role findRoleByName(String string) {
		return findByPropertyUnique(Role.class, "name", string);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Levels findLevelByPoint(Long point) {
		Criteria criteria=createCriteria(Levels.class);
		List<Levels> levels=criteria.list();
		Levels myLevel;
		Long max,min;
		for(int i=0;i<levels.size();i++){
			myLevel=levels.get(i);
			max=myLevel.getMax_val();
			min=myLevel.getMin_val();
			if(point<max){
				if(point>=min){
					return myLevel;
				}
			}
		}
		return levels.get(levels.size()-1);
	}

	@Override
	public List<User> getUsersBySearch(String q) {
		Criteria criteria = createCriteria(User.class);
		criteria.add(Restrictions.like("username", q, MatchMode.ANYWHERE));
		return criteria.list();
	}

	@Override
	public void saveReport(Report report) {
		getHibernateTemplate().save(report);
		
	}

	@Override
	public Report checkReported(String username, String username2) {
		Criteria criteria = createCriteria(Report.class);
		criteria.add(Restrictions.eq("reporter", username2)).add(Restrictions.eq("reported", username));
		return (Report) criteria.uniqueResult();
	}

	@Override
	public int getReportCount(String username) {
		Criteria criteria = createCriteria(Report.class);
		criteria.add(Restrictions.eq("reported", username));
		return criteria.list().size();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Report> getReportedOnes(String username2) {
		Criteria criteria = createCriteria(Report.class);
		criteria.add(Restrictions.eq("reporter", username2));
		return criteria.list();
	}

	@Override
	public Levels getTitle(Long levelPoint) {
		Criteria criteria = createCriteria(Levels.class);
		criteria.add(Restrictions.gt("max_val", levelPoint));
		criteria.add(Restrictions.lt("min_val", levelPoint));
		return (Levels) criteria.uniqueResult();
	}

	@Override
	public void sendRecoveryMail(String username, String email) {
		// TODO Auto-generated method stub
		
	}

}
